#include "DHT11.h"
#include "delay.h"

#define	DHT11_DataIO_OUT PEout(0)  //数据端口	PE0 
#define	DHT11_DataIO_IN  PEin(0)  //数据端口	PE0

void DHT11_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;


    // PE0
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    // 先设置为输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOE, &GPIO_InitStructure);

    GPIO_SetBits(GPIOE, GPIO_Pin_0);

}

void SetDataIO_Output()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;    // 先设置为输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOE, &GPIO_InitStructure);
}

void SetDataIO_Input()
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;    // 设置为输入
    GPIO_Init(GPIOE, &GPIO_InitStructure);
}


void DHT11_Reset(void)
{
    SetDataIO_Output();
    GPIO_ResetBits(GPIOE, GPIO_Pin_0);
    delay_ms(20);
    GPIO_SetBits(GPIOE, GPIO_Pin_0);
    delay_us(30);
}

uint8_t DHT11_Check()
{
    uint8_t retry = 0;
    SetDataIO_Input();

    // 等待DHT11响应信号的第一个下降沿（从高到低）
    while(DHT11_DataIO_IN)
    {
        retry++;
        delay_us(1);

        if (retry > 100)
        {
            printf("[Error] DHT11_Check: 111 timeout \r\n");
            break;
        }
    }

    retry = 0;

    // 等待DHT11响应信号的上升沿（从低到高）
    while(!DHT11_DataIO_IN)
    {
        retry++;
        delay_us(1);

        if (retry > 100)
        {
            printf("[Error] DHT11_Check: 222 timeout \r\n");
            break;
        }
    }

    // 最终检查是否超时，并返回结果
    if (retry > 100)
    {
        return 1;
    }
    return 0;
}

uint8_t DHT11_ReadBit()
{
    uint8_t retry = 0;

    // 等待变成低电平
    while(DHT11_DataIO_IN)
    {
        retry++;
        delay_us(1);

        if (retry > 100)
        {
            printf("[Error] DHT11_ReadBit: 111 timeout \r\n");
            break;
        }
    }

    retry = 0;

    // 等待变成高电平
    while(!DHT11_DataIO_IN)
    {
        retry++;
        delay_us(1);

        if (retry > 100)
        {
            printf("[Error] DHT11_ReadBit: 222 timeout \r\n");
            break;
        }
    }

    // 等待40us，表示0的高电平持续26us ~ 28us
    delay_us(40);

    // 在判断一次数据
    if (DHT11_DataIO_IN)
    {
        return 1;
    }

    return 0;
}

uint8_t DHT11_ReadByte()
{
    uint8_t i = 0;
    uint8_t data = 0;

    for (i = 0; i < 8; i++)
    {
        data <<= 1;
        data |= DHT11_ReadBit();
    }

    return data;
}


uint8_t DHT11_Read_AllData(uint8_t *humiInt, uint8_t *humiDec, uint8_t *tempInt, uint8_t *tempDec)
{
    uint8_t i = 0;
    uint8_t buf[5];
    uint8_t checksum = 0;

    DHT11_Reset();
    if (DHT11_Check() == 0)
    {
        for (i = 0; i < 5; i++)
        {
            buf[i] = DHT11_ReadByte();
        }

        checksum = buf[0] + buf[1] + buf[2] + buf[3];
        if (checksum == buf[4])
        {
            *humiInt = buf[0];
            *humiDec = buf[1];
            *tempInt = buf[2];
            *tempDec = buf[3];

            return 0;
        }
    }

    return 1;
}